package com.food.chain.security;

import java.util.concurrent.atomic.AtomicInteger;

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.cache.CacheManager;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.factory.annotation.Autowired;

import com.food.chain.common.util.EncryptUtil;


/**
 * 自定义密码验证
 * @author ruyi
 *
 */
public class CustomCredentialsMatcher extends SimpleCredentialsMatcher {
	
	private Cache<String, AtomicInteger> passwordRetryCache;

	/**
	 * 通过构造函数的方式注入
	 * @param customCacheManager
	 */
	public CustomCredentialsMatcher(CacheManager customCacheManager) {
		passwordRetryCache = customCacheManager.getCache("passwordRetryCache");
	}

	@Override
	public boolean doCredentialsMatch(AuthenticationToken itoken, AuthenticationInfo info) {
		UsernamePasswordToken token = (UsernamePasswordToken) itoken;
		
		String userName = (String) token.getPrincipal();
		AtomicInteger element = passwordRetryCache.get(userName);
		
		if (element == null) {
			element = new AtomicInteger(0);
			passwordRetryCache.put(userName, element);
		}
		
		if (element.incrementAndGet() > 5) {
			throw new ExcessiveAttemptsException("密码输入错误已超过5次");
		}
		
		// 获取用户输入的密码
		String psw = String.valueOf(token.getPassword());
		// 获取从数据库取得的密码
		Object credentials = getCredentials(info);
		
		// 加密对比
		boolean matches = BCrypt.checkpw(EncryptUtil.SHA512(psw), String.valueOf(credentials));
		
		if (matches) {
			passwordRetryCache.remove(userName);
		}
		
		return matches;
	}
}
